{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "44aba2a0-c6eb-4fc1-a5cc-0a8f8679dbb8",
   "metadata": {},
   "source": [
    "## Song-writing Assistant\n",
    "\n",
    "This app will use the GPT LLM to help you write a song that will make sure to have specific keywords in it that the user has entered. This app lets the user enter genres of music as well as specific artists to help tailor the assistant to the styles of music you want to incorprate in your song."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ad35f4c-ef77-4a87-b790-d3ffaf517ff0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Imports\n",
    "\n",
    "import os\n",
    "import requests\n",
    "from dotenv import load_dotenv\n",
    "from IPython.display import Markdown, display\n",
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e615a47-9dfa-48f3-b09a-db22d5462141",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load environment variables in a file called .env\n",
    "\n",
    "load_dotenv(override=True)\n",
    "api_key = os.getenv('OPENAI_API_KEY')\n",
    "\n",
    "# Check the key\n",
    "\n",
    "if not api_key:\n",
    "    print(\"No API key was found - please head over to the troubleshooting notebook in this folder to identify & fix!\")\n",
    "elif not api_key.startswith(\"sk-proj-\"):\n",
    "    print(\"An API key was found, but it doesn't start sk-proj-; please check you're using the right key - see troubleshooting notebook\")\n",
    "elif api_key.strip() != api_key:\n",
    "    print(\"An API key was found, but it looks like it might have space or tab characters at the start or end - please remove them - see troubleshooting notebook\")\n",
    "else:\n",
    "    print(\"API key found and looks good so far!\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d4d58124-5e9a-4f5a-9e0a-ff74f43896a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "openai = OpenAI()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7d33cc22-1dc0-4b49-a483-1c94fc466005",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initializing the genres set\n",
    "\n",
    "genres = []\n",
    "numOfGenres = int(input(\"How many genres would you like your assistant to know?\\nYou MUST enter at least 1, but you can enter up to 3: \"))\n",
    "\n",
    "while ((numOfGenres < 1) or (numOfGenres > 3)):\n",
    "    numOfGenres = int(input(\"\\nInvalid number of genres.\\nYou MUST enter at least 1, but you can enter up to 3: \"))\n",
    "\n",
    "print(f\"\\nEnter your genres below. Please keep in mind duplicate genres will be removed, so try to enter {numOfGenres} unique genres\")\n",
    "for g in range(numOfGenres):\n",
    "    genres.append(str(input(f\"Enter genre {g+1}: \")).lower())\n",
    "\n",
    "genres = set(genres)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ba7e045-ec3d-4555-ac56-badffa9f68f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initializing the music groups\n",
    "\n",
    "music_groups = []\n",
    "\n",
    "musicGroupsFlag = str(input(\"Would you like to add some singers/bands/groups that your assistant can be familar with? (Y/N)\")).lower()\n",
    "\n",
    "if(musicGroupsFlag == \"y\"):\n",
    "    numOfGroups = int(input(\"\\nHow many groups would you like your assistant to know?\\nYou MUST enter at least 1, but you can enter up to 3: \"))\n",
    "    while ((numOfGroups < 1) or (numOfGroups > 3)):\n",
    "        numOfGroups = int(input(\"\\nInvalid number of groups.\\nYou MUST enter at least 1, but you can enter up to 3: \"))\n",
    "\n",
    "    print(f\"\\nEnter your singers/bands/groups below. Please keep in mind duplicate singers/bands/groups will be removed, so try to enter {numOfGroups} unique singers/bands/groups.\")\n",
    "    for m in range(numOfGroups):\n",
    "        music_groups.append(str(input(f\"Enter singer/band/group {m+1}: \")))\n",
    "\n",
    "music_groups = set(music_groups)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69f75309-b179-4adc-979c-03d348dfb310",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initializing the keywords\n",
    "\n",
    "keywords = []\n",
    "numOfWords = int(input(\"How many keywords would you like add to your song?\\nYou MUST enter at least 1, but you can enter up to 20: \"))\n",
    "\n",
    "while ((numOfWords < 1) or (numOfWords > 20)):\n",
    "    numOfWords = int(input(\"\\nInvalid number of words.\\nYou MUST enter at least 1, but you can enter up to 20: \"))\n",
    "\n",
    "print(f\"\\nEnter your words below. Please keep in mind duplicate words will be removed, so try to enter {numOfWords} unique words\")\n",
    "for w in range(numOfWords):\n",
    "    keywords.append(str(input(f\"Word {w+1}: \")).lower())\n",
    "\n",
    "keywords = set(keywords)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3f53326-aeac-439b-8cb5-0ab1064df118",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Setting up the system and user prompts\n",
    "\n",
    "format_genres = \", \".join(genres)\n",
    "\n",
    "system_prompt = f\"You are a professional songwriter who has a specialty in the following genre(s) of music: {format_genres}.\"\n",
    "\n",
    "if(len(music_groups) > 0):\n",
    "    format_groups = \", \".join(music_groups)\n",
    "    system_prompt += f\"\\n\\nYou are also heavily familiar with the stylings of the following artist(s): {format_groups}\"\n",
    "\n",
    "system_prompt += \"\\n\\nUsing your knowledge of the genre(s) of music you know\"\n",
    "\n",
    "if(len(music_groups) > 0):\n",
    "    system_prompt += \", as well as the artist(s) you are familiar with\"\n",
    "\n",
    "system_prompt += \", your task will be to write a song that incorporates all of these influences while also making sure \\\n",
    "to use very specific keywords in that song. Please give your song in Markdown format.\"\n",
    "\n",
    "format_keywords = \", \".join(keywords)\n",
    "\n",
    "user_prompt = f\"I need you to write a song that has these specific keywords in it: {format_keywords}.\\n\\nMake sure that the song is in Markdown format\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67dc3099-2ccc-4ee8-8ff2-0dbbe4ae2fcb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Setting up the API\n",
    "\n",
    "messages = [\n",
    "    {\"role\": \"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": user_prompt},\n",
    "]\n",
    "    \n",
    "response = openai.chat.completions.create(\n",
    "        model = \"gpt-4o-mini\",\n",
    "        messages = messages\n",
    "    )\n",
    "\n",
    "# Printing the song in markdown format\n",
    "formatted_song = Markdown(response.choices[0].message.content)\n",
    "display(formatted_song)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
